package com.artPreter.config;


import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.artPreter.pojo.AlertMessage;
import com.artPreter.utils.HashMapEncoder;
import jakarta.websocket.*;
import jakarta.websocket.server.PathParam;
import jakarta.websocket.server.ServerEndpoint;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint(value = "/websocket/{userId}",encoders = {HashMapEncoder.class})
@Component
@Slf4j
public class WebSocketServer {

    /**静态变量，用来记录当前在线连接数。应该把它设计成线程安全的。*/
    private static int onlineCount = 0;
    /**concurrent包的线程安全集合，也可以map改成set，用来存放每个客户端对应的MyWebSocket对象。*/
    private static ConcurrentHashMap<String,WebSocketServer> webSocketMap = new ConcurrentHashMap<>();
    /**与某个客户端的连接会话，需要通过它来给客户端发送数据*/
    private Session session;
    /**接收userId*/
    private String userId="";


    /**
     * 连接建立成功调用的方法*/
    @OnOpen
    public void onOpen(Session session,@PathParam("userId") String userId) {
        this.session = session;
        this.userId=userId;

        if(!webSocketMap.containsKey(userId)){
            session.setMaxTextMessageBufferSize(10*1024*1024);
            session.setMaxBinaryMessageBufferSize(10*1024*1024);
            //加入集合中
            webSocketMap.put(userId,this);
            //在线数加1
            addOnlineCount();
        }

        log.info("用户连接:"+userId+",当前在线人数为:" + getOnlineCount());

        try {

            HashMap map = new HashMap();

            map.put("message","接收消息");
            map.put("code",200);

            List<HashMap> hashMapList = new ArrayList<>();
            for (int i = 0; i < 4; i++) {
                HashMap item = new HashMap();
                if(i==0){
                    item.put("name","温度");
                    item.put("status",0);
                    hashMapList.add(item);
                }else if(i==1){
                    item.put("name","湿度");
                    item.put("status",0);
                    hashMapList.add(item);
                }else if(i==2){
                    item.put("name","烟感");
                    item.put("status",0);
                    hashMapList.add(item);
                }else if(i==3){
                    item.put("name","漏水");
                    item.put("status",0);
                    hashMapList.add(item);
                }
            }
            map.put("data",hashMapList);



            this.session.getBasicRemote().sendObject(map);

        } catch (IOException e) {
            log.error("用户:"+userId+",网络异常!!!!!!");
        } catch (EncodeException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 连接关闭调用的方法
     */
    @OnClose
    public void onClose() {
        if(webSocketMap.containsKey(userId)){
            webSocketMap.remove(userId);
            //从集合中删除
            subOnlineCount();
        }
        log.info("用户退出:"+userId+",当前在线人数为:" + getOnlineCount());
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(String message, Session session) {

        log.info("【websocket消息】收到客户端发来的消息:{}", message);
    }

    /**
     *
     * @param session
     * @param error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.error("用户错误:"+this.userId+",原因:"+error.getMessage());
        error.printStackTrace();
    }
    /**
     * 实现服务器主动推送
     */
    public void sendMessage(String message) throws IOException {
        this.session.getBasicRemote().sendText(message);
    }

    public void sendAlertMessage(AlertMessage alertMessage) throws IOException {
        try {
            HashMap map = new HashMap();

            map.put("message","接收消息");
            map.put("code",200);

             List<HashMap> hashMapList = new ArrayList<>();
            for (int i = 0; i < 4; i++) {
                HashMap item = new HashMap();
                if(i==0){
                    item.put("name","温度");
                    item.put("status",0);
                    hashMapList.add(item);
                }else if(i==1){
                    item.put("name","湿度");
                    item.put("status",0);
                    hashMapList.add(item);
                }else if(i==2){
                    item.put("name","烟感");
                    item.put("status",0);
                    hashMapList.add(item);
                }else if(i==3){
                    item.put("name","漏水");
                    item.put("status",0);
                    hashMapList.add(item);
                }
            }

            if(alertMessage.getType()!=null){
                if(alertMessage.getType().equals(1)){
                    hashMapList.get(0).put("name","温度");
                    hashMapList.get(0).put("status",1);
                }else if(alertMessage.getType().equals(2)){
                    hashMapList.get(1).put("name","湿度");
                    hashMapList.get(1).put("status",1);
                }else if(alertMessage.getType().equals(3)){
                    hashMapList.get(2).put("name","烟感");
                    hashMapList.get(2).put("status",1);
                }else if(alertMessage.getType().equals(4)){
                    hashMapList.get(3).put("name","漏水");
                    hashMapList.get(3).put("status",1);
                }
            }else{
                    hashMapList.get(0).put("name","温度");
                    hashMapList.get(0).put("status",1);
            }



            map.put("data",hashMapList);

            this.session.getBasicRemote().sendObject(map);
        } catch (EncodeException e) {
            throw new RuntimeException(e);
        }
    }

    public void sendMap(HashMap hashMap) throws IOException {
        try {
            this.session.getBasicRemote().sendObject(hashMap);
        } catch (EncodeException e) {
            throw new RuntimeException(e);
        }
    }

    public static void sendAlertMessage(HashMap hashMap,@PathParam("userId") String userId) throws IOException {
        log.info("发送消息到:"+userId+"，报文:");
        if(StringUtils.isNotBlank(userId)&&webSocketMap.containsKey(userId)){
            webSocketMap.get(userId).sendMap(hashMap);
        }else{
            log.error("用户"+userId+",不在线！1");
        }
    }


    /**
     * 发送自定义消息
     * */
    public static void sendInfo(String message,@PathParam("userId") String userId) throws IOException {
        log.info("发送消息到:"+userId+"，报文:"+message);
        if(StringUtils.isNotBlank(userId)&&webSocketMap.containsKey(userId)){
            webSocketMap.get(userId).sendMessage(message);
        }else{
            log.error("用户"+userId+",不在线！2");
        }
    }

    public static void sendAlertMessage(AlertMessage message,@PathParam("userId") String userId) throws IOException {
        log.info("发送消息到:"+userId+"，报文:"+message.getMsg());
        if(StringUtils.isNotBlank(userId)&&webSocketMap.containsKey(userId)){
            webSocketMap.get(userId).sendAlertMessage(message);
        }else{
            log.error("用户"+userId+",不在线！3");
        }
    }

    public static synchronized int getOnlineCount() {
        return onlineCount;
    }

    public static synchronized void addOnlineCount() {
        WebSocketServer.onlineCount++;
    }

    public static synchronized void subOnlineCount() {
        WebSocketServer.onlineCount--;
    }


}
